home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Best of MacTutor - S…e Code for Volumes 1 to 5
/
The Best of MacTutor - Source Code for Volume 1-5 (Wayzata Technology)(6031)(1990).bin
/
Source Code
/
#45 (Jun 89)
/
Splitbar Test ƒ
/
MyScroll.Pas
< prev
next >
Wrap
Pascal/Delphi Source File
|
1989-03-28
|
7KB
|
227 lines
unit MyScroll;
interface
uses
MyGlobals;
procedure AdjustScrollBars; {reset max of scroll bars}
procedure AdjustText (pane: integer); {scroll to scrollbar value}
procedure ScrollCharacter; {scroll selection into view}
procedure ScrollToSelection; { figure which way to scroll}
procedure SetEditText (Index: integer); {Switch EditText to proper pane}
procedure FixTextRects; {resize EditText's rectangles and recalculate line starts}
procedure FixScrollbarRects; {resize and postion scroll/split bars}
procedure UpdateOtherPane; {invalidate non active pane's update area}
implementation
{ LinesInText is a kluge necessitated by a minor bug in TE. The bug is that if the last }
{ character in the TE text buffer is a Carriage Return, the field "nLines" may be off by one, }
{ and cause slightly incorrect updating of the window. This routine always returns the}
{ correct number of lines in the buffer. This is taken from Symantec's Think's Pascal}
function LinesInText: integer;
var
lines: integer;
txt: CharsHandle;
begin
with EditText^^ do
begin
lines := nLines;
txt := CharsHandle(hText);
if teLength > 0 then
if txt^^[teLength - 1] = CR then {Carriage Return?}
lines := lines + 1;
LinesInText := lines
end
end; {of LinesInText}
procedure AdjustScrollBars; {reset max of scroll bars}
var
ctlMax, index, height: integer;
begin
for index := 1 to 2 do {for each pane}
begin
SetEditText(index); {set pane}
with EditText^^ do
begin
height := (viewRect.bottom - viewRect.top) div lineHeight; {lines of text in viewRect}
ctlMax := LinesInText - height; {Control max}
if ctlMax < 0 then
ctlMax := 0;
SetCtlMax(Scroll[index], ctlMax)
end
end;
SetEditText(activePane); {reset EditText back to active pane}
end; {of AdjustScrollBars}
procedure AdjustText; {scroll to scrollbar value}
var
oldScroll, newScroll, delta: integer;
begin
SetEditText(pane);
with EditText^^ do
begin
oldScroll := viewRect.top - destrect.top; {get old scroll value}
newScroll := GetCtlValue(Scroll[pane]) * lineHeight; {get new scroll value}
delta := oldScroll - newScroll;
if delta <> 0 then
begin
TEScroll(0, delta, EditText); {scroll to new value}
end;
end;
destRect[pane] := EditText^^.destRect; {reset destRect for switching}
SetEditText(activepane); {reset to active pane}
end; {of AdjustText}
procedure ScrollCharacter; {scroll selection into view}
var
theLine, height: integer;
begin
HLock(Handle(EditText));
theLine := 0;
with EditText^^ do
begin
height := (viewRect.bottom - viewRect.top) div lineHeight;
while selStart >= lineStarts[theLine] do
theLine := theLine + 1;
SetCtlValue(Scroll[activePane], theLine - nLines div 2);
AdjustText(activePane);
end;
HUnLock(Handle(EditText));
end; {of scroll character}
procedure ScrollToSelection; {Figure which way to scroll to get selection}
var
topline, bottomline, height, max: integer;
begin
SetEditText(activePane);
HLock(Handle(EditText));
AdjustScrollBars;
AdjustText(activePane);
with EditText^^, viewRect do
begin
topline := GetCtlValue(Scroll[activePane]);
height := (bottom - top) div lineHeight;
bottomline := topline + height;
max := GetCtlMax(Scroll[activePane]);
if max = 0 then {all text within pane}
AdjustText(activePane)
else
ScrollCharacter; {need to scroll}
end;
HUnLock(Handle(EditText));
end; {of ScrollToSelection}
procedure SetEditText;
{Set EditText to indexed pane}
begin
EditText^^.viewRect := viewRect[Index];
EditText^^.destRect := destRect[Index];
end; {of SetEditText}
procedure FixTextRects; {adjust EditText's two panes}
begin
HLock(Handle(EditText));
viewRect[1] := MyWindow^.portRect; {set lower pane}
viewRect[1].top := Split^^.contrlValue + IndicatorWidth;
viewRect[1].right := viewRect[1].right - SBarWidth;
viewRect[1].bottom := viewRect[1].bottom - SBarWidth;
InsetRect(viewRect[1], Margin, Margin); {Give TE margins}
{Make viewRect a Multiple of lineHeight}
viewRect[1].bottom := viewRect[1].bottom - ((viewRect[1].bottom - viewRect[1].top) mod EditText^^.lineHeight);
destRect[1] := viewRect[1]; {Set destRect}
viewRect[2] := MyWindow^.portRect; {set upper pane}
viewRect[2].bottom := Scroll[2]^^.contrlRect.bottom;
viewRect[2].right := viewRect[2].right - SBarWidth;
InsetRect(viewRect[2], Margin, Margin); {Give TE margins}
{Make viewRect a multiple of lineHeight}
viewRect[2].bottom := viewRect[2].bottom - ((viewRect[2].bottom - viewRect[2].top) mod EditText^^.lineHeight);
destRect[2] := viewRect[2];
SetEditText(activePane); {Reset EditText back to active pane}
if EditText <> nil then {recalculate line starts}
begin
TECalText(EditText);
AdjustText(1);
AdjustText(2);
ScrollToSelection;
end;
HUnLock(Handle(EditText));
end; {of FixTextRects}
procedure FixScrollbarRects; {adjust scrollbars according to splitbar}
var
width, hieght: integer;
temp: rect;
begin
with MyWindow^.portRect do {get window dimensions}
begin
hieght := bottom - top - SBarWidth + 1;
width := right - left - SBarWidth + 1;
end;
SetRect(temp, width, 0, width + SBarWidth, hieght); {set control rectangles}
Split^^.contrlRect := temp;
Scroll[1]^^.contrlRect := Split^^.contrlRect;
Scroll[2]^^.contrlRect := Split^^.contrlRect;
Scroll[1]^^.contrlRect.top := Split^^.contrlValue + IndicatorWidth;
Scroll[2]^^.contrlRect.bottom := Split^^.contrlValue;
{check to see if there is enough room to draw scroll bars}
if (Scroll[2]^^.contrlRect.bottom - Scroll[2]^^.contrlRect.top) < SBarMinLen then
begin {not enough room, make invisible}
EraseRect(Scroll[2]^^.contrlRect);
Scroll[2]^^.contrlVis := invisible;
end
else {enough room, make visible}
Scroll[2]^^.contrlVis := visible;
if (Scroll[1]^^.contrlRect.bottom - Scroll[1]^^.contrlRect.top) < SBarMinLen then
begin {not enough room, make invisible}
EraseRect(Scroll[1]^^.contrlRect);
Scroll[1]^^.contrlVis := invisible;
end
else {enough room, make visible}
Scroll[1]^^.contrlVis := visible;
if EditText <> nil then {fix TE rectangles}
begin
FixTextRects;
EraseRect(MyWindow^.portRect);
InvalRect(MyWindow^.portRect);
end;
end;{ of FixScrollbarRects}
procedure UpdateOtherPane; {invalidate non active pane for updating}
var
tempRect: array[1..2] of rect;
delta: array[1..2] of integer;
i, index: integer;
pane: rect;
intersect: boolean;
begin
case activePane of {get non active pane}
1:
index := 2;
2:
index := 1;
end;
for i := 1 to 2 do {normalize viewRects to check for overlapp}
begin
delta[i] := destRect[i].top;
tempRect[i] := viewRect[i];
OffsetRect(tempRect[i], 0, -delta[i]);
end;
intersect := SectRect(tempRect[1], tempRect[2], pane); {get intersection}
OffsetRect(pane, 0, delta[index]); {place intersection to correct area on window}
if intersect then {invalidate intersecting rectangle}
InvalRect(pane);
end; {of UpdateOtherPane}
end.